#!/usr/bin/python3
# ******************************************************************************
# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
# licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# ******************************************************************************/
import json
import os
import constant
from logger import logger

PR_NUMBER = -1
REPO = -3


def extract_repo_pull(pr: str):
    if not pr:
        return None
    pr = pr.split("/")
    try:
        repo, number = pr[REPO], pr[PR_NUMBER]
    except IndexError:
        return None
    return repo, number


def get_project_name(repo, pr_number):
    return f"ci_test:{repo}:{pr_number}"


class ProcessRecords:
    """过程的结果数据记录"""

    file_pointer = None
    steps = [
        "single_build_check",
        "single_install_check",
        "diff_analysis",
        "multi_build_check",
        "multi_install_check",
    ]

    def __init__(self, package, pr) -> None:
        self._file = os.path.join(constant.RECORDS_COURSE, package + "-" + pr)
        self._progress = self._execute_progress()

    def _execute_progress(self):
        if os.path.exists(self._file):
            return self.content.get("execution_progress", self.progress)
        return self.progress

    @property
    def progress(self):
        if not self.content:
            return dict(
                current_progress=self.steps[0],
                next_progress=self.steps[0:],
            )
        return self.content.get("execution_progress")

    @progress.setter
    def progress(self, progress):
        progress_index = self._progress["next_progress"].index(progress)
        self._progress["next_progress"] = self._progress["next_progress"][
            progress_index:
        ]

    def _set_pointer(self):
        try:
            self.file_pointer = open(self._file, "a", encoding="utf-8")
        except IOError as error:
            logger.error(f"Error opening file {self._file},error info: {error}")
            raise

    @property
    def content(self):
        if not self.file_pointer:
            self._set_pointer()
        try:
            return json.loads(self.file_pointer.read())
        except json.JSONDecodeError as error:
            logger.warning(f"Json decode error: {error}")
            return dict()

    def update_check_options(self, steps, check_result: dict):
        if steps != "pr_link_reult" and steps not in self.steps:
            raise ValueError(f"The {steps} step does not exist in ci check.")
        content = self.content
        content[steps] = check_result
        self.save(progress=steps, content=content)

    def save(self, progress, content):
        if progress not in self.steps:
            raise ValueError(f"The {progress} step does not exist in ci check.")
        self.progress = progress
        if content is None and not isinstance(content, dict):
            raise ValueError("The content saved is not a dict typical data.")

        content["execution_progress"] = self.progress
        if content.get("diff_analysis") and not content["diff_analysis"].get(
            "need_verify"
        ):
            content["execution_progress"]["next_progress"] = []
        try:
            if self.file_pointer is None:
                self._set_pointer()

            self.file_pointer.write(json.dumps(content))
        except IOError as error:
            logger.error(f"Failed to save the progress information: {error}")
        finally:
            self.file_pointer.close()
